﻿#pragma once

#include "common.h"
#include "editor/inspector.h"
#include "editor/settings.h"

namespace anip
{
	namespace editor
	{
		namespace drawing
		{
			struct StylusData
			{
				bool hasContact = false;
				bool hasOrientation = false;
				bool hasPressure = false;

				vec2 contactSize{ 0, 0 };
				vec2 contactOffset{ 0, 0 };
				float orientation = 0;
				float pressure = 0.5f;
			};

			class Tool : public InspectorContentProvider
			{
			private:
				bool _active;

			protected:
				virtual void processActivate() {};
				virtual void processDeactivate() {};

				virtual void processCreateUI(ui::Container& c) override {}
				virtual void processDeleteUI(ui::Container& c) override {}

			public:
				virtual ~Tool() = default;

				virtual Texture2D* getIcon() = 0;

				// ANIP_UNDONE: remove this, use a categorical design (e.g. drawing 
				// tools, aligning tools etc) where tools within the same category
				// are mutually exclusive
				
				// an exclusive tool cannot be used together with any other
				virtual bool isExclusive() const { return true; }

				void activate();
				void deactivate();

				bool isActive() const { return _active; }

				// Note: `pos` refers to the physical position, not the one in the 
				// `FrameGroup`'s coordinate system, of the cursor.
				virtual void drawGizmo(invec2 pos) = 0;

				virtual void drawGlobalBackground(GraphicsRenderContext& cxt) {}
				virtual void drawFrameGroupBackground(GraphicsRenderContext& cxt) {}
				virtual void drawForeground(GraphicsRenderContext& cxt) {}
				virtual void drawOverlay(GraphicsRenderContext& cxt) {}

				// The following group of functions returns `true` if ANY action is
				// taken. `pos` is given in the `FrameGroup`'s coordinate system.

				virtual bool beginStroke(DrawingArea& area, 
					MouseButton btn, invec2 pos, const StylusData& data) 
				{ return false; }

				virtual bool strokePoint(DrawingArea& area, 
					invec2 pos, const StylusData& data)
				{ return false; }

				virtual bool endStroke(DrawingArea& area) { return false; }

				virtual bool mouseButton(MouseButton btn, ButtonAction act) { return false; }
				virtual bool mouseMove(invec2 pos) { return false; }
			};

			class PointerTool : public Tool
			{
			private:
				static PreloadedTexture
					icon, cursor;

			public:
				wstring name() const override { return L"指针"; }
				Texture2D* getIcon() override { return icon.get(); }

				void drawGizmo(invec2 pos) override;
			};
		}
	}
}